package com.github.gin.sns.util;

import com.github.gin.sns.annotation.XmlRoot;

import java.io.File;
import java.lang.annotation.Annotation;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by GinPonson on 2017/1/1.
 */
public class AnnotationScaner {

    private static final Pattern pattern  = Pattern.compile("(classes\\S)([\\S]*)(\\.class)");

    public static Class[] findClassByAnnotation(Class<? extends Annotation> annotation){
        File rootDirectory = getRootDirectory();

        List<String> classFileList = new ArrayList<>();
        findClassRecursively(rootDirectory,classFileList);

        Class[] classes = new Class[classFileList.size()];
        for(int i = 0; i < classFileList.size(); i++){
            Matcher matcher = pattern.matcher(classFileList.get(i));
            if(matcher.find()){
                Class clazz = classforName(matcher.group(2).replace("\\","."));
                if (clazz.isAnnotationPresent(annotation)){
                    classes[i] = clazz;
                }
            }
        }
        return classes;
    }

    private static File getRootDirectory(){
        File rootDirectory = null;
        try {
            rootDirectory = new File(AnnotationScaner.class.getClassLoader().getResource("").toURI());
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return rootDirectory;
    }

    private static void findClassRecursively(File rootDirectory,List<String> classFileList){
        if(rootDirectory.isDirectory()){
            for(File file : rootDirectory.listFiles()){
                if(file.getName().endsWith(".class")){
                    classFileList.add(file.getPath());
                }
                findClassRecursively(file,classFileList);
            }
        }
    }

    private static Class classforName(String className){
        Class clazz = null;
        try {
            clazz = Class.forName(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return clazz;
    }

    public static void main(String[] args) throws Exception {
        System.out.println(findClassByAnnotation(XmlRoot.class));
    }
}
